//  
//    String+Extention.swift
//    weibo
//  
//    Created by tianXin on 2017/3/13.
//    Copyright © 2017年 tianXin. All rights reserved.
//  

import Foundation
import CoreGraphics
import UIKit

extension String {

    //  MARK: Calculated properties
    //   Checking if String is Empty
    var isBlank: Bool {
        
        return self.removeWhiteSpaces == "" ? true:false
    }
    
    //   Checking if String is Empty or "(null)"
    var isValid: Bool {
        
        return (self.removeWhiteSpaces == "" || self == "(null)") ? false : true
    }
    
    //   Checking if String is empty or nil
    static func isValid(_ string: String?)->Bool {
        
        guard let string = string else {
            
            return false
        }
        
        return string.removeWhiteSpaces.isValid
    }
    
    //   remove white spaces from String
    var removeWhiteSpaces: String {
        
     return self.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
    }
    
    //   Counts number of Words in String
    var countNumberOfWords: Int {
        
        let scanner = Scanner.init(string: self)
        let whiteSpace = CharacterSet.whitespaces
        var count = 0
        
        while  scanner.scanCharacters(from: whiteSpace, into: nil){
            
            count += count
        }
        
        return count
    }
    
    //   If my string contains ony letters
    var containsOnlyLetters: Bool {
        
        let letterCharacterset = CharacterSet.letters.inverted
        return (((self as NSString).rangeOfCharacter(from: letterCharacterset)).location == NSNotFound)
    }
    
    //   If my string contains only numbers
    var containsOnlyNumbers: Bool {
        
        let numbersCharacterSet = CharacterSet.init(charactersIn: "0123456789").inverted;
        return (((self as NSString).rangeOfCharacter(from: numbersCharacterSet)).location == NSNotFound)
    }
    
    //   If my string contains letters and numbers
    var containsOnlyNumbersAndLetters: Bool {
        
        let numAndLetterCharSet = CharacterSet.alphanumerics.inverted
        return (((self as NSString).rangeOfCharacter(from: numAndLetterCharSet)).location == NSNotFound)
    }
    
    //   If my string contains none letters and numbers
    var containsNoneNumbersAndLetters: Bool {
        
        let numAndLetterCharSet = CharacterSet.alphanumerics
        return (((self as NSString).rangeOfCharacter(from: numAndLetterCharSet)).location == NSNotFound)
    }
    
    //  Whether it contains Chinese
    var containsChineseCharacters: Bool {
        
        for i in 0 ..< self.characters.count - 1 {
            let c = (self as NSString).character(at: i)
            if ( c > 0x4e00 && c < 0x9fff)  {
                return true
            }
        }
        
        return false
    }
    
    //  Calculate the length of the string
    var containsOnlyChineseCharacters: Int {
        
        var number = 0
        guard self.characters.count > 0 else {return 0}
        for i in 0...self.characters.count - 1 {
            
            let c: unichar = (self as NSString).character(at: i)
            
            if (c >= 0x4E00) {
                number += 2
            }else {
                number += 1
            }
        }
        
        return number
    }
    
    //  contains Emoji
    var containsEmoji: Bool {
        
        for scalar in unicodeScalars {
            
            switch scalar.value {
            case
            0x00A0...0x00AF,
            0x2030...0x204F,
            0x2120...0x213F,
            0x2190...0x21AF,
            0x2310...0x329F,
            0x1F000...0x1F9CF:
                return true
            default:
                continue
            }
        }
        return false
    }
    
    //   Convert Array from my String
    var getArray: [String]? {
        
        return self.components(separatedBy: " ")
    }
    
    //   Get My Application Version number
    var getMyApplicationVersion: String? {
        
        return Bundle.main.version
    }
    
    //   Get My Application name
    var getMyApplicationName: String? {
        
        return Bundle.main.displayName
    }
    
    //   Convert string to NSData
    var convertToData: Data? {
        
        return self.data(using: .utf8)
    }
    
    //   Is Valid Email
    var isValidEmail: Bool{
        
        let regex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let emailTestPredicate = NSPredicate(format: "SELF MATCHES \(regex)")
        
        return emailTestPredicate.evaluate(with:self)
    }
    
    //   Is Valid Phone
    var isVAlidPhoneNumber: Bool{
        
        let regex = "[235689][0-9]{6}([0-9]{3})?"
        let emailTestPredicate = NSPredicate(format: "SELF MATCHES \(regex)")
        
        return emailTestPredicate.evaluate(with:self)
    }
    
    //   Is Valid Email
    var isVAlidMobelNumber: Bool{
        
        let regex = "[1][0-9]{10}"
        let emailTestPredicate = NSPredicate(format: "SELF MATCHES \(regex)")
        
        return emailTestPredicate.evaluate(with:self)
    }
    
    //   Is Valid Email
    var isValidUrl: Bool{
        
        let regex = "(http|https)://  ((\\w)*|([0-9]*)|([-|_])*)+([\\.|/]((\\w)*|([0-9]*)|([-|_])*))+"
        let emailTestPredicate = NSPredicate(format: "SELF MATCHES \(regex)")
        
        return emailTestPredicate.evaluate(with:self)
    }
    
    //   Is Valid Email
    var checkUsername: Bool{
        
        let regex = "^[A-Za-z0-9]{1,15}$"
        let emailTestPredicate = NSPredicate(format: "SELF MATCHES \(regex)")
        
        return emailTestPredicate.evaluate(with:self)
    }
    //  Is Mobile
    var isMobileNumber: Bool {
        
        let mobileNum = self;
        /**
         * 手机号码
         * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
         * 联通：130,131,132,152,155,156,185,186
         * 电信：133,1349,153,180,189
         */
        let  MOBILE = "^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
        /**
         10         * 中国移动：China Mobile
         11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188,183
         12         */
       let CM = "^1(34[0-8]|(3[5-9]|5[017-9]|8[2378])\\d)\\d{7}$";
        /**
         15         * 中国联通：China Unicom
         16         * 130,131,132,152,155,156,185,186
         17         */
        let CU = "^1(3[0-2]|5[256]|8[56])\\d{8}$";
        /**
         20         * 中国电信：China Telecom
         21         * 133,1349,153,180,189
         22         */
        let CT = "^1((33|53|8[09])[0-9]|349)\\d{7}$";
        /**
         25         * 大陆地区固话及小灵通
         26         * 区号：010,020,021,022,023,024,025,027,028,029
         27         * 号码：七位或八位
         28         */
        let PHS = "^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
        
        let regextestmobile = NSPredicate(format: "SELF MATCHES \(MOBILE)");
        let regextestcm = NSPredicate(format: "SELF MATCHES \(CM)");
        let regextestcu = NSPredicate(format: "SELF MATCHES \(CU)");
        let regextestct = NSPredicate(format: "SELF MATCHES \(CT)");
        let regextestphs = NSPredicate(format: "SELF MATCHES \(PHS)");
        
        if ((regextestmobile.evaluate(with: mobileNum) == true)
            || (regextestcm.evaluate(with: mobileNum) == true)
            || (regextestcu.evaluate(with: mobileNum) == true)
            || (regextestct.evaluate(with: mobileNum) == true)
            || (regextestphs.evaluate(with: mobileNum) == true))
        {
            
            return true;
            
        } else {
            
            return false;
        }
    }
    
    //  MD5 String
    var md5 : String {
        
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        
        for i in 0 ..< digestLen {
            
            hash.appendFormat("%02x", result[i])
        }
        result.deinitialize()
        
        return String(format: hash as String)
    }
    
    // MARK: Method
    //   If my string is available in particular array
    func isIn(_ array: [AnyObject]) -> Bool {
        
        for objc in array {
            
            if objc is String ,let obj = objc as? String ,obj == self {
                
                return true
            }
        }
        return false
    }
    
    //   Get String from array
    func getStringFromArray(_ array: [AnyObject]) -> String? {
        
        var tempArray :[String]?
        for objc in array {
            
            if objc is String ,let obj = objc as? String  {
                
                tempArray?.append(obj)
            }
        }
        return tempArray?.joined(separator: " ")
    }
    
    //   If string contains substring
    func contains(_ subString: String) -> Bool {
        
        return ((self as NSString).range(of: subString).location == NSNotFound) ? false : true
    }
    
    //   If my string starts with given string
    func isBegins(_ string: String) -> Bool {
        
        return (hasPrefix(string)) ? true : false
    }
    
    //    If my string ends with given string
    func isEndss(_ string: String) -> Bool {
        
        return (hasSuffix(string)) ? true : false
    }
    
    //  Replace particular characters in my string with new character
    func replaceCharcter(_ olderChar: String, withCharcter newerChar: String) -> String {
        
        return replacingOccurrences(of: olderChar, with: newerChar)
    }
    
    //   Get Substring from particular location to given lenght
    func getSubstringFrom(_ begin: Int, to end: Int) -> String {
        
        var r = _NSRange()
        r.location = begin
        r.length = end - begin
        
        return (self as NSString).substring(with: r)
    }
    
    //   Add substring to main String
    func addString(_ string: String?) -> String {
        
        if (string == nil) || string?.characters.count == 0 {
            
            return self
        }
        return self + string!
    }
    
    //   Remove particular sub string from main string
    func removeString(_ subString: String) -> String {
        
        if self.contains(subString) ,let range = self.range(of: subString) {
            
            return self.replacingCharacters(in: range, with: "");
        }
        return self
    }
    
    //   Get String from NSData
    func getStringFromData(_ data: Data) -> String? {
        
        return String.init(data: data, encoding: .utf8)
    }
}
